package com.yin.myproject.util;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.web.context.ContextLoader;

import java.util.Collection;
import java.util.Map;

/**
 * @author Eason
 * @create 2018-04-08 14:19
 **/
public class ApplicationContextUtil implements ApplicationContextAware {

    private static final Logger logger = LoggerFactory.getLogger(ApplicationContextUtil.class);
    private static ApplicationContext ctx;

    /**
     * 获取上下文实例
     * @return
     */
    public static ApplicationContext getContext() {
        if(ctx == null) {
            logger.info("context is null. wait for ContextLoader");
            ctx = ContextLoader.getCurrentWebApplicationContext();
            logger.info("context init finished. {}", ctx);
        }
        return ctx;
    }

    /**
     * 设置上下文实例
     * @param context
     */
    @Override
    public void setApplicationContext(ApplicationContext context) {
        logger.info("init context. {}", context);
        ctx = context;
    }

    /**
     * 获取指定class的Type单个实例
     * @param clazz
     * @return
     */
    public static <T> T getBean(Class<T> clazz) {
        return getContext().getBean(clazz);
    }

    /**
     * 获取指定name和class的Type单个实例
     * @param name
     * @param clazz
     * @return
     */
    public static <T> T getBeanByNameAndClazz(String name, Class<T> clazz) {
        return getContext().getBean(name, clazz);
    }

    /**
     * 通过指定名称获取对应实例
     * @param name
     * @return
     */
    public static Object getBeanByName(String name) {
        return getContext().getBean(name);
    }

    /**
     * 获取指定class的Type的多个实例（包含子类型实例）的已name为key，以实例对象为value的map集合
     * @param clazz
     * @return
     */
    public static <T> Map<String, T> getBeansMap(Class<T> clazz) {
        return getContext().getBeansOfType(clazz);
    }

    /**
     * 获取指定class的Type的多个实例（包含子类型实例）的集合
     * @param clazz
     * @return
     */
    public static <T> Collection<T> getBeans(Class<T> clazz) {

        Map<String, T> beansMap = getBeansMap(clazz);

        if(beansMap == null || beansMap.isEmpty()) {
            return null;
        }

        return beansMap.values();
    }

}